﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Animator))]
public abstract class unit : RepManager
{
    private bool canReceiveDMG=true;
    [SerializeField]
    private string unitName;
    [SerializeField]
    private Sprite avatar;
    
    [SerializeField]
    private float spd, atkSpeed=1;
    public Transform MyTrgt { get; set; }
    public Animator MyAnimator { get; set; }
    [SerializeField]
    protected Text lvlText;
                                       // protected float xInput;
                                       //  protected float yInput;
    private float xdir;//animation direction x
    private float ydir;//animation direction y
    public bool IsAlive
    {
        get
        {

            if (health != null)
            {
                return Health.myVal > 0;
            }
            else
            {
                return true;
            }
        }
    }
    public bool IsCasting { get; set; }
    public bool IsAttacking { get; set; }
    protected Rigidbody2D prb;
    private SpriteRenderer spr;
    protected Vector3 direction;//non normalize playr move
    protected Coroutine spellCast;
    [SerializeField]
    protected Transform hitbox;
    // Start is called before the first frame update
    protected static bool HPbarShow;
    [SerializeField]
    private stats health;
    
    //[SerializeField]
    //protected int initLevel;
    [SerializeField]
    private int level;
    protected int startHealth;
    [SerializeField]
    protected int initHealth;
    
    

    protected virtual void Start()
    {
        startHealth = (initHealth * level);
        if (health != null)
        {
            Health.inicialize(startHealth, startHealth);
        }
        MyAnimator = GetComponent<Animator>();
        prb = GetComponent<Rigidbody2D>();
        spr = GetComponent<SpriteRenderer>();
        if (MyAnimator)
        {
            MyAnimator.SetFloat("atkSpeed", atkSpeed);
        }
        
    }
   
    // Update is called once per frame
    protected virtual void Update()
    {
        move();
    }

    protected virtual void move()
    {
        direction = new Vector3(Xdir, Ydir, 0);
       
        prb.velocity = direction.normalized * MySpd;
        if(MyAnimator != null)
        {
            animateMove(Xdir, Ydir);
        }
        
       
    }
    protected bool IsMoving
    {
        get
        {
            return Xdir != 0 || Ydir != 0;

        }
    }

    public float Ydir { get => ydir; set => ydir = value; }
    public float Xdir { get => xdir; set => xdir = value; }
    public float MySpd { get => spd; set => spd = value; }
    public stats Health { get => health; set => health = value; }
    public string MyName { get => unitName; set => unitName=value; }
    public Sprite MyAvatar { get => avatar;  }
    public float MyAtkSpeed { get => atkSpeed; set => atkSpeed = value; }
    public int MyLevel { get => level; set => level = value; }
    public bool MyCanReceiveDMG { get => canReceiveDMG; set => canReceiveDMG = value; }

    public virtual void animateMove(float x, float y)
    {
        if (IsAlive)
        {

            if (IsMoving)
            {
                activeLayerController("move");
                MyAnimator.SetFloat("x", x);
                MyAnimator.SetFloat("y", y);
                denieCast();
            }
            else if (IsCasting)
            {
                activeLayerController("cast");
            }
            else if (IsAttacking)
            {
                MyAnimator.SetFloat("atkSpeed", atkSpeed);
                activeLayerController("atk");
            }
            else
            {
                activeLayerController("idle");

            }
        }
        else
        {
            activeLayerController("death");
        }
    
    }
    public virtual void activeLayerController(string layerName)//complete armor animation
    {
   
        for(int i = 0; i < MyAnimator.layerCount; i++)
        {
            MyAnimator.SetLayerWeight(i, 0);
        }
        MyAnimator.SetLayerWeight(MyAnimator.GetLayerIndex(layerName), 1);
    }
    public virtual void denieCast()
    {
        if(spellCast != null)
        {
            StopCoroutine(spellCast);
            IsCasting = false;
            MyAnimator.SetBool("cast", IsCasting);
        }
    }
    public virtual void ReceiveDMG(float dmg, Transform source)
    {
        if (MyCanReceiveDMG)
        {
            if (MyTrgt == null)//ne perekluchaty
            {
                MyTrgt = source;
            }
            Health.myVal -= dmg;
            sctManager.MyInstance.TextGen(dmg.ToString(), transform.position, SCTType.DAMAGE, false);
            if (Health.myVal <= 0)
            {
                MyAnimator.SetTrigger("die");
                MyCanReceiveDMG = false;
                //spd = 0;
                xdir = 0;
                ydir = 0;
                if (this is npc)
                {
                    Player.MyInstance.GetXP(ExpManager.CalcExp(this));
                }
            }
        }
    }
    public void GetHealth(int health)
    {
        Health.myVal += health;
        
        sctManager.MyInstance.TextGen(health.ToString(), transform.position,SCTType.HEALING,true);
    }
    public void RefreshLvl()
    {
        lvlText.text = MyLevel.ToString();
    }
}
